package javango.contrib.compat;

import java.io.Serializable;

import javango.db.Manager;
import javango.db.ManagerException;
import javango.forms.Form;
import javango.forms.fields.Field;
import javango.http.Http404;
import javango.http.Http500;
import javango.http.HttpException;

import com.google.inject.Inject;
import com.google.inject.Injector;

public class Javango {

	private Injector injector;
	
	@Inject
	public Javango(Injector injector) {
		super();
		this.injector = injector;
	}

	public javango.db.Managers Managers() {
		return injector.getInstance(javango.db.Managers.class);
	}
	
	public javango.forms.Forms Forms() {
		return injector.getInstance(javango.forms.Forms.class);
	}
	
	public <T> Manager<T> newManager(Class<T> model) {
		return Managers().forClass(model);
	}
	
	public <T extends Form> T newForm(Class<T> formClass) {
		return Forms().newForm(formClass);
	}
	
	public <T extends Field<?>> T newField(Class<T> fieldClass) {
		return injector.getInstance(fieldClass);
	}
	
	public <T> T getObject(Class<T> model, Serializable key) throws ManagerException {
		Manager<T> manager = Managers().forClass(model);
		
		try {
			return manager.get(key);
		} catch (ManagerException e) {
			throw new ManagerException(String.format("A database eror occurred while getting an instance of '%s' with key '%s'", model.getName(), key));
		}
	}

	public <T> T getObject(Class<T> model, String field, Object value) throws ManagerException {
		Manager<T> manager = Managers().forClass(model);
		
		try {
			return manager.filter(field, value).get();
		} catch (ManagerException e) {
			throw new ManagerException(String.format("A database eror occurred while getting an instance of '%s' with %s='%s'", model.getName(), field, value));
		}
	}

	public <T> T getObjectOr404(Class<T> model, Serializable key) throws HttpException {
		try {
			T object = getObject(model, key);
			if (object == null) {
				// 	TODO Make the error message a little cleaner,  maybe don't use the full class name.
				throw new Http404(String.format("Unable to find '%s' instance with key '%s'", model.getName(), key));			
			}
			return object;
		} catch (ManagerException e) {
			throw new Http500(e.getMessage());
		}
		
	}

	public <T> T getObjectOr404(Class<T> model, String field, Object value) throws HttpException {
		Manager<T> manager = Managers().forClass(model);
		
		try {
			T object = manager.filter(field, value).get();
			if (object == null) {
				// 	TODO Make the error message a little cleaner,  maybe don't use the full class name.
				throw new Http404(String.format("Unable to find '%s' instance with '%s' of '%s'", model.getName(), field, value));			
			}
			return object;
		} catch (ManagerException e) {
			throw new Http500(e.getMessage());
		}
	}

		
}
